/*
 * FileWalker.java
 *
 * Created on 2 September 2006, 1:41
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package fasea.index;

import fasea.model.IndexingFolder;
import fasea.utils.FileUtil;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.apache.commons.io.FilenameUtils;

/**
 *
 * @author gvasil
 * @author lars-wolfram
 */
class FileWalker {

    private ArrayList<File> fileList;
    private HashSet<File> directories;
    private List<String> fileExtensions;

    /**
     * Creates a new instance of FileWalker
     */
    public FileWalker(IndexingFolder dir) throws IOException {
        if (!dir.getIndexingFolder().exists()) {
            throw new IOException("Directory " + dir + " does not exist.");
        }
        if (!FileUtil.isDirectory(dir.getIndexingFolder())) {
            throw new IOException("File " + dir + " is not a directory.");
        }
        if (!dir.getIndexingFolder().canRead()) {
            throw new IOException("Cannot read directory " + dir + ".");
        }

        this.fileList = new ArrayList<File>();
        this.fileList.add(dir.getIndexingFolder().getCanonicalFile());
        this.fileExtensions = dir.getFileExtensionRestrictions();
        this.directories = new HashSet<File>();
    }

    public boolean hasNext() {
        return !fileList.isEmpty();
    }

    public File next() {
        File f = null;
        do {
            if (!fileList.isEmpty()) {
                f = fileList.remove(fileList.size() - 1);
                if (FileUtil.isDirectory(f)) {
                    putFilesFromDirInFileList(f);
                }
            }

        } while (!fileExtensions.isEmpty() && FileUtil.isDirectory(f) && !fileList.isEmpty());
        return f;
    }

    private void putFilesFromDirInFileList(File dir) {
        this.directories.add(dir);
        File[] filesInDirectory;
        if (fileExtensions.isEmpty()) {
            filesInDirectory = dir.listFiles();
        } else {
            filesInDirectory = dir.listFiles(new FileFilter() {

                public boolean accept(File file) {
                    if (FileUtil.isDirectory(file)) {
                        return true;
                    } else {
                        String fileExtension = FilenameUtils.getExtension(file.getName());
                        for (String fileExtensionRestrictions : fileExtensions) {
                            if (fileExtensionRestrictions.equalsIgnoreCase(fileExtension)) {
                                return true;
                            }
                        }
                        return false;
                    }
                }
            });
        }
        if (filesInDirectory != null) {
            for (File file : filesInDirectory) {
                if (file.exists() && file.canRead() && !this.directories.contains(file)) {
                    fileList.add(file);
                }
            }
        }
    }
}
